/*==============================================
 * Task3b: The Block Maze
 *
 * Written by <YOUR NAME HERE>
 *
 *==============================================*/

#include "GameUtils.h"
#include "SceneEngine.h"
#include "Node.h"
#include "Maze.h"

/** Task 3b: The maze
*/
class CTask3b: public CScene
{
	CXMesh* mpPlayerMesh;
	CMeshNode mPlayer;
	CXMesh* mpGroundMesh;
	CXMesh* mpCrateMesh;
	CXMesh* mpCoinMesh;
	CMaze* mpMaze;

public:
	void Enter();
	void Update(float dt);
	void Draw(float dt);
	void Leave();
};

void CTask3b::Enter()
{
	mpGroundMesh=new CXMesh(GetDevice(),"media/checker.x");
	mpPlayerMesh=new CXMesh(GetDevice(),"media/yellow_ball.x");
	mpCrateMesh=new CXMesh(GetDevice(),"media/crate.x");
	mpCoinMesh=new CXMesh(GetDevice(),"media/coin.x");
	mpMaze=new CMaze(mpCrateMesh,mpCoinMesh);
	mpMaze->Init("media/maze.txt");

	// setup scene
	SetupDefaultD3DOptions(GetDevice(),true);
	// overhead view, looking at the middle of the maze
	// (maze is 10x10, so middle is 5,0,5)
	// (- a little bit on the Z so its not straight up-down)
	CameraLookAt(GetDevice(),D3DXVECTOR3(10,5,-2),D3DXVECTOR3(5,1,2));

	mPlayer.Init(mpPlayerMesh,D3DXVECTOR3(1,0.5,1));
}
void CTask3b::Update(float dt)
{
	CScene::Update(dt);	// VITAL
	if (CGameWindow::KeyPress(VK_F10))
		ExitScene();

	D3DXVECTOR3 oldPos = mPlayer.GetPos();

	// basic movement:
	const float SPEED=1.0f;
	D3DXVECTOR3 move(0,0,0);
	if (CGameWindow::KeyDown('W'))	move.z++;
	if (CGameWindow::KeyDown('S'))	move.z--;
	if (CGameWindow::KeyDown('A'))	move.x--;
	if (CGameWindow::KeyDown('D'))	move.x++;
	mPlayer.MoveGround(move*dt*SPEED);

	// rotation code:
	const float TURN_SPEED=D2R(45);
	if (CGameWindow::KeyDown(VK_LEFT))	mPlayer.Yaw(-TURN_SPEED*dt);
	if (CGameWindow::KeyDown(VK_RIGHT))	mPlayer.Yaw(+TURN_SPEED*dt);
	if (CGameWindow::KeyDown(VK_UP))	mPlayer.Pitch(-TURN_SPEED*dt);
	if (CGameWindow::KeyDown(VK_DOWN))	mPlayer.Pitch(+TURN_SPEED*dt);

	if (mpMaze->IsClear(mPlayer.GetPos(),0.45f))
		GetEngine()->SetTitle("Clear");
	else
	{
		GetEngine()->SetTitle("Wall");
		mPlayer.SetPos(mpMaze->WallSlide(oldPos,mPlayer.GetPos(),0.45f));
	}
	// TODO: you should replace this with some real code
	// which stops people from walking through walls
	// or even makes them slide on walls
}
void CTask3b::Draw(float dt)
{
    // Clear the backbuffer to a black color
    GetDevice()->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BLUE_COL, 1.0f, 0 );
	GetDevice()->BeginScene();

	// draw ground so its centres on the maze
	mpGroundMesh->Draw(D3DXVECTOR3(5,0,5));
	mpMaze->Draw();
	mPlayer.Draw();


	GetDevice()->EndScene();
}
void CTask3b::Leave()
{
	SAFE_DELETE(mpGroundMesh);
	SAFE_DELETE(mpPlayerMesh);
	SAFE_DELETE(mpCrateMesh);
	SAFE_DELETE(mpMaze);
}


int WINAPI WinMain(HINSTANCE hInstance, 
				   HINSTANCE hPrevInstance, 
				   LPTSTR lpCmdLine, int nCmdShow)
{
    ENABLE_LEAK_DETECTION();	// Enable run-time memory check for debug builds.
	CSceneEngine eng(640,480,false);
	eng.AddScene(new CTask3b);
	return eng.Go(hInstance);	// runs everything
}
